﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Server.ActivityFeed;
using ESF.SharePoint.Utility;

using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.SharePoint.Common.ServiceLocation;
using ESF.SharePoint.Formatters;
using Microsoft.SharePoint;
using ESF.SharePoint.Entities;

namespace ESF.SharePoint.ActivityAggregators.Providers
{
    public class ProfileChangePropertyActivityAggregatorProvider : ActivityAggregatorBaseProvider
    {
        private string FormatterName = "ProfileChangePropertyFormatter";

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);

            // Get the ServiceLocatorConfig service from the service locator.
            IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
            IServiceLocatorConfig typeMappings =
                                  serviceLocator.GetInstance<IServiceLocatorConfig>();

            SPSite currentSite = SPContext.Current.Site;
            SPWeb currentWeb = currentSite.RootWeb;
            currentWeb.AllowUnsafeUpdates = true;
            typeMappings.Site = currentSite;
            typeMappings.RegisterTypeMapping<IActivityFormatter, ProfileChangePropertyFormatter>(FormatterName);
            SharePointServiceLocator.Reset();
        }

        public override List<CustomActivityEvent> ProcessActivities(List<CustomActivityEvent> source)
        {
            base.ActivityTypeId = 1;
            base.Formatter = FormatterName;

            List<Entity> usersWithUpdatedProfile = new List<Entity>();
            List<CustomActivityEvent> eventsToRemove = new List<CustomActivityEvent>();

            CustomActivityEvent lastActivityOfTheDay = null;

            // Getting only activities of the selected TypeId
            var events = from e in source
                         where e.ActivityTypeId == ActivityTypeId
                         select e;

            DateTime date = DateTime.MinValue;
            foreach (var customEvent in events)
            {

                if (date == DateTime.MinValue)
                    date = customEvent.CreationTime;

                // If current feed is related to new day reset counter
                if (date.DayOfYear != customEvent.CreationTime.DayOfYear)
                {
                    // Update last feed with all users that changed user profile
                    ProcessAndFormatEvent(usersWithUpdatedProfile, lastActivityOfTheDay);
                    lastActivityOfTheDay = null;

                    usersWithUpdatedProfile.Clear();
                }

                // Collect users that changed user profile properties
                Entity key = customEvent.Publisher;
                if (!usersWithUpdatedProfile.Exists(delegate(Entity t)
                { return key.AccountName == t.AccountName; }))
                {
                    usersWithUpdatedProfile.Add(key);
                }

                // Collect activities to remove
                if (lastActivityOfTheDay != null)
                    eventsToRemove.Add(lastActivityOfTheDay);
                lastActivityOfTheDay = customEvent;
            }

            // Update last feed with all users that changed user profile
            ProcessAndFormatEvent(usersWithUpdatedProfile, lastActivityOfTheDay);

            // Remove items
            foreach (var eventToRemove in eventsToRemove)
            {
                source.Remove(eventToRemove);
            }

            return source;
        }

        private void ProcessAndFormatEvent(List<Entity> usersWithUpdatedProfile, CustomActivityEvent lastActivityOfTheDay)
        {
            if (lastActivityOfTheDay != null)
            {
                IActivityFormatter formatter =
                    ServiceLocatorHelper.GetServiceInstance<IActivityFormatter>(SPContext.Current.Site, Formatter);
                lastActivityOfTheDay = formatter.Format(lastActivityOfTheDay, usersWithUpdatedProfile);
            }
        }
    }
}
